﻿using System;
using Needle.Framework;
using Needle.Utils;
using SC =  System.Configuration;

namespace Needle.Core.Configuration
{
    /// <summary>
    /// 
    /// </summary>
    public class ConfigurationLoader : LifetimeComponent 
    {
        private string _ConfigurationFilename;
        /// <summary>
        /// The file to load.
        /// </summary>
        public string ConfigurationFileName
        {
            get {
                if (String.IsNullOrEmpty(_ConfigurationFilename))
                {
                    if (AppFileSystem.ConfigFile != null) 
                    {
                        return AppFileSystem.ConfigFile.FullName;   
                    }
                }
                return _ConfigurationFilename; 
            }
            set
            {
                if (!DesignMode)
                    Ensure.ValidOperation(!IsInitialized, "Loader already initialized");
                _ConfigurationFilename = value;
            }
        }

        private string _ConfigurationSectionName;
        /// <summary>
        /// The configuration section name
        /// </summary>
        public string ConfigurationSectionName
        {
            get {
                if (String.IsNullOrEmpty(_ConfigurationSectionName))
                {
                    return NeedleConfiguration.DefaultSectionName;
                }
                return _ConfigurationSectionName; }
            set
            {
                if (!DesignMode)
                    Ensure.ValidOperation(!IsInitialized, "Loader already initialized");
                _ConfigurationSectionName = value;
            }
        }

        private NeedleConfiguration _Configuration;
        /// <summary>
        /// The Configuration section.
        /// </summary>
        public NeedleConfiguration Configuration
        {
            get {
                if(!DesignMode)
                    Ensure.ValidOperation(IsInitialized, "Loader not initialized yet");
                return _Configuration;
            }
        }
        /// <summary>
        /// End initialization.
        /// </summary>
        public override void EndInit()
        {
            LoadConfiguration();
            base.EndInit();
        }

        private void LoadConfiguration()
        {
            SC.Configuration cfg;
            cfg = LoadAppConfiguration();
            _Configuration = LoadNeedleConfiguration(cfg);
            ConfigureKernel(_Configuration);
        }

        private void ConfigureKernel(NeedleConfiguration _Configuration)
        {
            throw new NotImplementedException();
        }

        private NeedleConfiguration LoadNeedleConfiguration(SC.Configuration cfg)
        {
            string sectionName;
            if (String.IsNullOrEmpty(_ConfigurationSectionName))
                sectionName = NeedleConfiguration.DefaultSectionName;
            else
                sectionName = _ConfigurationSectionName;
            return NeedleConfiguration.Get(cfg, sectionName);
        }

        private SC.Configuration LoadAppConfiguration()
        {
            SC.Configuration cfg;
            if (String.IsNullOrEmpty(_ConfigurationFilename))
            {
                cfg = SC.ConfigurationManager.OpenExeConfiguration(SC.ConfigurationUserLevel.None);
            }
            else
            {
                SC.ExeConfigurationFileMap fileMap = new SC.ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = _ConfigurationFilename;
                cfg = SC.ConfigurationManager.OpenMappedExeConfiguration(fileMap, SC.ConfigurationUserLevel.None);
            }
            return cfg;
        }

    }
}
